/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2000-2001 Intel Corporation. All Rights Reserved.
//
//  Description:
//      Intel(R) JPEG library for X platform 
//
********************************************************************************/
#include "_ijx.h"

extern const Ipp8u _nIZigZagIndex[64];

/******************************************************************************
// Name:            ijHuffmanDecode_ACFirst
// Description:     Decoding scan data (AC first) for progressive mode
// Input Arguments:
//              ss: Start position of data block in ZZ order.    
//              ss: End position of data block in ZZ order.
//              al: Indicates approximation low
//        pComSpec: Identifies IJCOMPSPEC data structure.
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficients buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijHuffmanDecode_ACFirst(Ipp16s      *pMCUBuf, 
                                   int         ss, 
                                   int         se,
                                   int         al,
                                   IJCOMPSPEC  *pComSpec,
                                   IJBITTREAMSTATE *pStream,
                                   IJDECODESTATE *pDecodeState)
{
    int i, j, x, y, nIdent;
    int nHSampling, nVSampling;
    int nHMCUCount, nVMCUCount;
    int nImageWidth, nImageHeight;
    int nOffset, nMCUOffset, nMCULen;

    Ipp16s *pMCUBufCur;
    IJMCUSPEC *pMCUSpec;
    IJCOMPSPEC *pCompSpec;
    IppJPEGDeHuffTable *pACHuffTable;
    IJXRESULT rtCode;

    pMCUSpec=&(pDecodeState->mcuSpec);
    pCompSpec=pDecodeState->scanSpec.ppCompSpec[0];
    nIdent=pComSpec->nACHuffTableIndex;
    pACHuffTable=&(pDecodeState->acHuffTable[nIdent]);

    nHSampling=pCompSpec->nHSampling;
    nVSampling=pCompSpec->nVSampling;
    nHMCUCount=pMCUSpec->nHMCUCount;
    nVMCUCount=pMCUSpec->nVMCUCount;
    nImageWidth=pDecodeState->imageSpec.nWidth; 
    nImageHeight=pDecodeState->imageSpec.nHeight;

    if (0<pMCUSpec->nMCUPadWidth) nHMCUCount++;
    if (0<pMCUSpec->nMCUPadHeight) nVMCUCount++;

    nMCULen     = ((nVSampling*nHSampling)<<6);
    nMCUOffset  = nMCULen * nHMCUCount;


    //Interleaved order
    for (y=0; y<nVMCUCount; y++) {
        for (j=0; j<nVSampling; j++) {
            if (((y*nVSampling+j)<<3)>=nImageHeight) {
                break;
            }
            for (x=0; x<nHMCUCount; x++) {
                nOffset=(y*nMCUOffset)+(x*nMCULen)+((j * nHSampling)<<6);
                pMCUBufCur=pMCUBuf+nOffset;
                for (i=0; i<nHSampling; i++) {
                    if (((x*nHSampling+i)<<3)>=nImageWidth) {
                        break;
                    }
                    rtCode=ippiDecodeHuffman_Direct_JPEG_ACFirst_1u16s(pStream->pBitStream,  
                                                                &(pStream->nUsedBufBitsLen),
                                                                pMCUBufCur,
                                                                &(pDecodeState->progSpec.nEOBRun),
                                                                &(pStream->nMarker),
                                                                &(pStream->nPrefetchedBits),
                                                                &(pStream->nNumValidPrefetchedBits),
                                                                ss, se, al,
                                                                pACHuffTable);
                    pMCUBufCur+=64;
                    if ( (0<pDecodeState->nRstInterval) ){
                        pDecodeState->counter.nDRICounter--;
                        if (0==pDecodeState->counter.nDRICounter) {
                            ijAdjustRestartIntervalInv(pStream,pDecodeState);
                        }
                    }
                }//for (i=0; i<nHSampling; i++)
            }//for (x=0; x<nHMCUCount; x++)
        }//for (j=0; j<nVSampling; j++)
    }//for (y=0; y<nVMCUCount; y++) 

    pDecodeState->progSpec.nEOBRun=0;

//    pDecodeState->counter.nScanMCUCounter++;

    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijHuffmanDecode_ACRefine
// Description:     Decoding scan data (AC refine) for progressive mode
// Input Arguments:
//              ss: Start position of data block in ZZ order.    
//              ss: End position of data block in ZZ order.
//              al: Indicates approximation low
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
// Output Arguments:
//         pMCUBuf: Identifies MCU coefficients buffer.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijHuffmanDecode_ACRefine(Ipp16s      *pMCUBuf, 
                                    int         ss, 
                                    int         se,
                                    int         al,
                                    IJCOMPSPEC  *pComSpec,
                                    IJBITTREAMSTATE *pStream,
                                    IJDECODESTATE *pDecodeState)
{
    int i, j, x, y, nIdent;
    int nHSampling, nVSampling;
    int nHMCUCount, nVMCUCount;
    int nImageWidth, nImageHeight;
    int nOffset, nMCUOffset, nMCULen;

    Ipp16s *pMCUBufCur;
    IJMCUSPEC *pMCUSpec;
    IJCOMPSPEC *pCompSpec;
    IJPROGRESSIVESPEC *pProgSpec;
    IppJPEGDeHuffTable *pACHuffTable;
    IJXRESULT rtCode;

    pMCUSpec=&(pDecodeState->mcuSpec);
    pProgSpec=&(pDecodeState->progSpec);
    pCompSpec=pDecodeState->scanSpec.ppCompSpec[0];
    nIdent=pComSpec->nACHuffTableIndex;
    pACHuffTable=&(pDecodeState->acHuffTable[nIdent]);

    nHSampling=pCompSpec->nHSampling;
    nVSampling=pCompSpec->nVSampling;
    nHMCUCount=pMCUSpec->nHMCUCount;
    nVMCUCount=pMCUSpec->nVMCUCount;
    nImageWidth=pDecodeState->imageSpec.nWidth; 
    nImageHeight=pDecodeState->imageSpec.nHeight;

    if (0<pMCUSpec->nMCUPadWidth) nHMCUCount++;
    if (0<pMCUSpec->nMCUPadHeight) nVMCUCount++;

    nMCULen     = ((nVSampling*nHSampling)<<6);
    nMCUOffset  = nMCULen * nHMCUCount;

    //Interleaved order
    for (y=0; y<nVMCUCount; y++) {
        for (j=0; j<nVSampling; j++) {
            if (((y*nVSampling+j)<<3)>=nImageHeight) {
                break;
            }
            for (x=0; x<nHMCUCount; x++) {
                nOffset=(y*nMCUOffset)+(x*nMCULen)+((j * nHSampling)<<6);
                pMCUBufCur=pMCUBuf+nOffset;
                for (i=0; i<nHSampling; i++) {
                    if (((x*nHSampling+i)<<3)>=nImageWidth) {
                        break;
                    }
                    rtCode=ippiDecodeHuffman_Direct_JPEG_ACRefine_1u16s(pStream->pBitStream,  
                                                                &(pStream->nUsedBufBitsLen),
                                                                pMCUBufCur,
                                                                &(pDecodeState->progSpec.nEOBRun),
                                                                &(pStream->nMarker),
                                                                &(pStream->nPrefetchedBits),
                                                                &(pStream->nNumValidPrefetchedBits),
                                                                ss, se, al,
                                                                pACHuffTable);
                    pMCUBufCur+=64;
                    if ( (0<pDecodeState->nRstInterval) ){
                        pDecodeState->counter.nDRICounter--;
                        if (0==pDecodeState->counter.nDRICounter) {
                            ijAdjustRestartIntervalInv(pStream,pDecodeState);
                        }
                    }
                }// for (i=0; i<nHSampling; i++)
            } // for (x=0; x<nHMCUCount; x++)
        } // for (j=0; j<nVSampling; j++)
    }//for (y=0; y<nVMCUCount; y++)

    pDecodeState->progSpec.nEOBRun=0;

//    pDecodeState->counter.nScanMCUCounter++;

    return IJX_RTCODE_OK;
}

/* EOF */
